#include <unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_ARGC 64
#define SEP " "
#define SIZE 1024
char *argv[MAX_ARGC];
char pwd[SIZE];
char env[SIZE];//环境变量表
int lastcode=0;
const char* HostName()
{
    char* hostname=getenv("HOSTNAME");
    if(hostname)
        return hostname;
    return "Not Found";
}

const char* UserName()
{
    char* username=getenv("USER");
    if(username)
        return username;
    return "Not Found";
}

const char* Currentdir()
{
    char* currendir=getenv("PWD");
        if(currendir)
            return currendir;
        return "Not Found";
}
char *Home()
{
    return getenv("HOME");
}

int Iterative(char command[],int size)
{
    printf("[%s@%s %s ]$ ",UserName(),HostName(),Currentdir());
    fgets(command,size,stdin);
    //目的是为了不要读取'\n'
    command[strlen(command)-1]=0;
    
    return strlen(command);
}

void Spilt(char com[])
{
    //ls -a
    int i=0;
    argv[i++]=strtok(com,SEP);//举例 ls
    while(argv[i++]=strtok(NULL,SEP));//举例 -a 
}

void Execute()
{
    pid_t id=fork();
    if(id==0)
    {
        execvp(argv[0],argv);
        exit(1);
    }
    int status=0;
    pid_t rid= waitpid(id,&status,0);
    if(rid==id)
        lastcode=WEXITSTATUS(status);//获取子进程退出状态

}

int isIncmd()
{
    int ret=0;
    
    //
    if(strcmp("cd",argv[0])==0)
    {
        ret=1;
        char* tmp=argv[1];
        if(!tmp)
            tmp=Home();
        //改变当前的工作目录
        chdir(tmp);
        char buffer[SIZE];
        //将当前的工作目录的绝对路径保存到buffer数组中
        getcwd(buffer,SIZE);
        //将buffer数组中的内写入到pwd数组中 
        snprintf(pwd,SIZE,"PWD=%s",buffer);
        //输出环境变量到环境变量表中
        putenv(pwd);
    }
    else if(strcmp("export",argv[0])==0)
    {
        ret=1;
        if(argv[1])
        {
            strcpy(env,argv[1]);
            putenv(env);
        }
    }
    else if(strcmp("echo",argv[0])==0)
    {
        ret=1;
        if(argv[1]==NULL)
            printf("\n");
        else
        {
            if(argv[1][0]=='$')
            {
                if(argv[1][1]=='?')
                {
                    printf("%d\n",lastcode);
                    lastcode=0;
                }
                else
                {
                    char* e=getenv(argv[1]+1);
                    if(e)
                        printf("%s\n",e);
                }
             }
            else
            {
                printf("%s\n",argv[1]);
            }
        }
    }
    return ret;
}
int main()
{
    
    while(1)
    {   
        char command[SIZE];
        
        //获取输入的字符串
        int ret=Iterative(command,SIZE);
        if(!ret)
            continue;

        //分割字符串，将ls -a
        //分解为ls
        //      -a
        Spilt(command);
      
        //检测是否是内建命令，例如cd，echo，export
        ret=isIncmd();
        if(ret)
            continue;
        //子进程执行命令
        Execute();
    }
    
}

